<template>
  <div id="app">
    <el-tabs v-model="siderType"
             class="sider">
      <el-tab-pane label="图层"
                   name="layer">
        <!-- 图层列表 -->
        <sortable v-model="list"
                  @change="onSortChange">
          <transition-group>
            <div class="layer"
                 v-for="item in list"
                 :key="item.id">
              {{ item.label }}
            </div>
          </transition-group>
        </sortable>

      </el-tab-pane>
      <el-tab-pane label="组件"
                   name="widget">
        <!-- 组件列表 -->
        <widget-list :list="widgetList"
                     @onWidgetMouseDown="onWidgetMouseDown" />
      </el-tab-pane>
    </el-tabs>

    <div class="warrp">
      <SketchRule :lang="lang"
                  :thick="thick"
                  :scale="scale"
                  :width="width"
                  :height="height"
                  :startX="startX"
                  :startY="startY"
                  :shadow="shadow"
                  :horLineArr="lines.h"
                  :verLineArr="lines.v"
                  :cornerActive="true"
                  @handleLine="handleLine"
                  @onCornerClick="handleCornerClick">
      </SketchRule>
      <div ref='screensRef'
           id="screens"
           @scroll="handleScroll">
        <div ref="containerRef"
             class="screen-container">
          <div id="canvas"
               :style="canvasStyle">
            <div @dragover.prevent
                 @drop="onDrop"
                 class="panel"
                 ref="panel">

              <dragger v-for="(item,i) in list"
                       :key="item.id"
                       :w="item.w"
                       :h="item.h"
                       :x="item.x"
                       :y="item.y"
                       :z="item.z"
                       :minw="5"
                       :minh="5"
                       class="box"
                       ref="widget"
                       :isResizable="true"
                       :isActive="item.focused"
                       @contextmenu.native.prevent="onContextMenuOpen($event, item)"
                       @clicked="onFocus(item)"
                       @resizestop="record"
                       @dragstop="record">
                <component :value="item.value"
                           :styles="item.styles"
                           class="inner-widget"
                           :is="item.component"
                           @drop.native.stop="onDrop($event, i)" />
              </dragger>

            </div>

          </div>
        </div>
      </div>
    </div>

    <div class="sider right">
      <style-sider :current="current"
                   :form="currentForm" />

    </div>

    <context-menu ref="contextMenu">
      <li>
        <a href="#"
           @click.prevent="onLayerTop">置顶</a>
      </li>
      <li>
        <a href="#"
           @click.prevent="onLayerBottom">置底</a>
      </li>
      <li>
        <a href="#"
           @click.prevent="onLayerUp">上移图层</a>
      </li>
      <li>
        <a href="#"
           @click.prevent="onLayerDown">下移图层</a>
      </li>
      <li>
        <a href="#"
           @click.prevent="onLayerRemove">删除</a>
      </li>
    </context-menu>

  </div>

</template>
<script>
// 小组件列表
import WidgetList from '@/components/widget-list';
// 样式配置区域
import StyleSider from '@/components/style-sider';
// 左侧小组件
import BarChart from '@/components/bar-chart';
import AreaChart from '@/components/area-chart';
import CustomText from '@/components/custom-text';
import CustomVideo from '@/components/custom-video';
import CustomImg from '@/components/custom-img';
import CustomInput from '@/components/custom-input';
// 右键菜单
import ContextMenu from 'vue-context';
// 静态配置
import * as CONFIG from '@/constants/config';
import { cloneDeep } from 'lodash';
import EventBus from '@/utils/eventBus'
//刻度尺
import SketchRule from "vue-sketch-ruler";
//生成唯一id
import { v4 as uuidv4 } from 'uuid';
let currentId = 0;
let widgetX = 0;//当前组件坐标
let widgetY = 0;
let currentWidget = null;//当前组件
// 用于撤回的记录
const recordList = [];
// 用于反撤回的记录
const recordList4ctrlY = [];
//默认数据
let defaultList = [
  {
    component: "custom-img",
    focused: false,
    h: 300,
    id: uuidv4(),
    label: "图片",
    type: "image",
    styles: {
      backgroundImage: "https://img.tukuppt.com/photo-big/00/00/94/6152bc0ce6e5d805.jpg"
    },
    w: 400,
    x: 624,
    y: 194,
    z: 1,
  },
  {
    component: "custom-input",
    focused: false,
    h: 30,
    id: uuidv4(),
    label: "输入框",
    type: "input",
    styles: {
    },
    w: 400,
    x: 595,
    y: 500,
    z: 2,
  }
]


export default {
  data () {
    return {
      siderType: 'widget',//右侧菜单切换
      list: defaultList,
      widgetList: CONFIG.WIDGET_LIST,//默认可拖拽组件列表

      //刻度尺数据
      scale: 1,
      startX: 0,
      startY: 0,
      // 初始化参考线
      lines: {
        h: [],
        v: []
      },
      //标尺厚度
      thick: 20,
      //放置标尺窗口的宽高
      width: 1200,
      height: 900,
      lang: "zh-CN", // 中英文
      isShowRuler: true, // 显示标尺
      isShowReferLine: true // 显示参考线
    }
  },
  components: {
    WidgetList,
    BarChart,
    AreaChart,
    CustomText,
    CustomVideo,
    ContextMenu,
    StyleSider,
    CustomImg,
    CustomInput,
    SketchRule
  },
  watch: {
    list (newVal) {
      console.log("list", newVal);
    }
  },
  computed: {
    current () {
      return this.list.find(item => item.focused);
    },
    currentForm () {
      if (!this.current) {
        return [];
      }
      return CONFIG.WIDGET_LIST.find(item => this.current.type === item.type).styleForm;
    },
    shadow () {
      return {
        x: 0,
        y: 0,
        width: 0,
        height: 0
      }
    },
    canvasStyle () {
      return {
        width: '100vw',
        height: '100vh',
        transform: `scale(${this.scale})`
      }
    }
  },
  methods: {
    onKeyDown (e) {
      // e.preventDefault();
      // switch (e.key) {
      //   case 'Shift':
      //     // this.multiable = true;
      //     break;

      //   default:
      //     break;
      // }
    },
    onKeyUp (e) {
      // e.preventDefault();
      // switch (e.key) {
      //   case 'Shift':
      //     // this.multiable = false;
      //     break;

      //   default:
      //     break;
      // }
      // ctrl + z 撤回
      if (e.ctrlKey && e.key === 'z') {
        this.withdraw();
      }
      // ctrl + y 反撤回
      if (e.ctrlKey && e.key === 'y') {
        this.ctrlY();
      }
      // ctrl + s 保存
      if (e.ctrlKey && e.key === 's') {
        // this.save();
      }
    },
    // 记录list
    record (rect) {
      if (rect) {
        // 更新list
        const current = this.list.find(item => item.focused);
        current.x = rect.left;
        current.y = rect.top;
        current.w = rect.width;
        current.h = rect.height;
      }

      recordList.push(cloneDeep(this.list));
    },
    // 撤回
    withdraw () {
      if (recordList.length === 0) {
        alert('撤回到底了');
        return;
      }
      const idx = recordList.length - 2; // -1
      if (idx === -1) {
        this.list = [];
      } else {
        this.list = recordList[idx]
      }
      const tmp = recordList.pop();
      recordList4ctrlY.push(tmp);
    },
    // 反撤回
    ctrlY () {
      this.list = recordList4ctrlY.pop();
      this.record();
    },

    onSortChange () {
      const len = this.list.length;
      this.list.forEach((item, i) => {
        item.z = len - i;
      });
    },
    // 给list排序
    sortList () {
      this.list.sort((a, b) => b.z - a.z);
    },
    //找到最高层级的图层
    findTopLayerZ (currentItem) {
      const maxZ = Math.max(...this.list.map(item => item.z)) || 0;
      if (currentItem.z === maxZ) {
        alert('已经是最顶层了');
        return;
      }
      return maxZ;
    },
    findBottomLayerZ (currentItem) {
      const minZ = Math.min(...this.list.map(item => item.z)) || 0;
      if (currentItem.z === minZ) {
        alert('已经是最底层了');
        return false;
      }
      return minZ;
    },
    //置顶
    onLayerTop () {
      const currentItem = this.list.find(item => item.focused);
      const maxZ = this.findTopLayerZ(currentItem)
      if (maxZ === false) {
        return;
      }
      currentItem.z = maxZ + 1;
      this.sortList()
      this.record();
    },
    // 置底
    onLayerBottom () {
      const currentItem = this.list.find(item => item.focused);
      const minZ = this.findBottomLayerZ(currentItem)
      if (minZ === false) {
        return;
      }
      if (minZ - 1 < 0) {
        this.list = this.list.map(item => {
          item.z -= minZ - 1;
          return item;
        });
        currentItem.z = 0;
      } else {
        currentItem.z = minZ - 1;
      }
      this.sortList()
      this.record();
    },
    //上移图层
    onLayerUp () {
      const currentItem = this.list.find(item => item.focused);
      if (!this.findTopLayerZ(currentItem)) {
        return;
      }
      currentItem.z++
      // 楼上的
      const upstairs = this.list.find(item => item.z === currentItem.z && item.id !== currentItem.id);
      upstairs && (upstairs.z--)
      this.sortList()
      this.record();
    },
    //下移图层
    onLayerDown () {
      const currentItem = this.list.find(item => item.focused);
      if (this.findBottomLayerZ(currentItem) === false) {
        return;
      }
      currentItem.z--
      // 楼上的
      const downstairs = this.list.find(item => item.z === currentItem.z && item.id !== currentItem.id);
      downstairs && (downstairs.z++)
      this.sortList()
      this.record();
    },
    //移除图层
    onLayerRemove () {
      this.list = this.list.filter(item => !item.focused);
      this.sortList()
    },
    //选中组件获取焦点
    onFocus (currentItem) {
      this.list = this.list.map(item => {
        item.focused = item.id === currentItem.id;
        return item;
      });
    },
    // 右键菜单打开事件
    onContextMenuOpen (e, item) {
      // 打开右键菜单
      this.$refs.contextMenu.open(e);
      // 给当前项获取焦点
      this.onFocus(item)
    },
    //创建组件
    onDrop (e, i) {
      let x = e.offsetX - widgetX;
      let y = e.offsetY - widgetY;
      // 放置在其他图层上时
      if (i !== undefined) {
        x += this.list[i].x;
        y += this.list[i].y;
      }
      // 关闭右键菜单
      this.$refs.contextMenu.close();
      const newItem = {
        id: uuidv4(),
        x,
        y,
        // 新增的面板项层级应该最高
        z: !this.list.length
          ? 0
          : Math.max(...this.list.map(item => item.z)) + 1,
        ...currentWidget.default,
        // w:this.findDefaultWithType (currentWidget.type).w ,
        // h:this.findDefaultWithType (currentWidget.type).h,
        styles: cloneDeep(currentWidget.styles), // 新增组件的类型
        label: currentWidget.label,
        component: currentWidget.component,
        type: currentWidget.type
      }
      this.list.push(newItem)
      this.onFocus(newItem)
      this.sortList()
      this.record();
    },
    // 在小组件鼠标落下的时候
    onWidgetMouseDown (e, widget) {
      widgetX = e.offsetX;
      widgetY = e.offsetY;
      console.log(currentWidget);
      currentWidget = widget;
    },

    // 通过type找宽高信息
    findDefaultWithType (type) {
      return CONFIG.WIDGET_LIST.find(item => item.type === type).default;
    },




    //刻度尺
    handleLine (lines) {
      this.lines = lines;
    },
    handleCornerClick () {
      return;
    },
    handleScroll () {
      const screensRect = document
        .querySelector("#screens")
        .getBoundingClientRect();
      const canvasRect = document
        .querySelector("#canvas")
        .getBoundingClientRect();

      // 标尺开始的刻度
      const startX = (screensRect.left + this.thick - canvasRect.left) / this.scale;
      const startY = (screensRect.top + this.thick - canvasRect.top) / this.scale;

      this.startX = startX;
      this.startY = startY;
    },


  },
  mounted () {
    EventBus.$on('changeSty', (id, type, val) => {
      this.list = this.list.map((item) => {
        if (item.id === id) {
          if (type === 'x') {
            item.x = val
          } else if (type === 'y') {
            item.y = val
          } else if (type === 'w') {
            item.w = val
          } else if (type === 'h') {
            console.log("val", val);
            item.h = val
          } else {
            item.styles.backgroundImage = val
          }
        }
        return item;
      });
    })
    this.handleScroll()


      let favicon = document.querySelector('link[rel="icon"]')
      if (favicon !== null) {
        favicon.href = '/favicon1.ico'
      } else {
        favicon = document.createElement('link')
        favicon.rel = 'icon'
        favicon.href ='/favicon1.ico'
        document.head.appendChild(favicon)
      }

  }
}
</script>
<style lang="less">
body {
  margin: 0;
}

#app {
  display: flex;
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
/*修改滚动条样式*/
div::-webkit-scrollbar {
  /*滚动条整体样式*/
  width: 5px;
  /*高宽分别对应横竖滚动条的尺寸*/
  height: 5px;
}

div::-webkit-scrollbar-track {
  background: rgba(37, 37, 40, 0.15);
}

div::-webkit-scrollbar-thumb {
  background: rgba(134, 190, 255, 0.25);
  //opacity: 0.15;
}

div::-webkit-scrollbar-thumb:hover {
  background: rgba(134, 190, 255, 0.5);
}
.sider {
  width: 200px;
  background: #e9e9e9;
}

.sider.right {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 308px;
}

.panel {
  background: #f6f6f6;
  position: relative;
  height: 100%;
  width: 1990px;
}

.center {
  flex: 1;
  background: #f6f6f6;
  position: relative;
  width: 100%;
  overflow: auto;
}

.box {
  position: absolute;
}

.inner-widget {
  height: 100%;
  width: 100%;
}

.layer {
  width: 100%;
  height: 50px;
  background: #fff;
}

.layer:hover {
  background: #e9e9e9;
}

.standard-line {
  height: 100%;
  width: 5px;
  background: rgba(255, 0, 0, 0.211);
  position: absolute;
  left: 200px;
}

.standard-line.correct {
  background: red;
}

.warrp {
  background-color: #f5f5f5;
  position: absolute;
  top: 0;
  left: 200px;
  width: 1200px;
  height: 900px;
  border: 1px solid #dadadc;
}

#screens {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow: auto;
}

.screen-container {
  position: absolute;
  width: 1990px;
  height: 1150px;
}
</style>